package com.njtoyo.taxi.admin.service.business.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njtoyo.taxi.admin.mapper.master.entity.CallPrepayRule;
import com.njtoyo.taxi.admin.mapper.master.mapper.CallPrepayRuleMapper;
import com.njtoyo.taxi.admin.mongo.entity.primary.CallGeoCircleFenceMongo;
import com.njtoyo.taxi.admin.mongo.repository.primary.CallGeoCircleFenceMongoRepository;
import com.njtoyo.taxi.admin.rest.presenter.business.operation_rule.call_prepay_rule.CallPrepayRulePresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.operation_rule.call_prepay_rule.CallPrepayFenceWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.operation_rule.call_prepay_rule.CallPrepayRuleAddUpdateWrapper;
import com.njtoyo.taxi.admin.service.business.CallPrepayRuleService;
import com.taxi.entity.common.RestResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Service
public class CallPrepayRuleServiceImpl extends ServiceImpl<CallPrepayRuleMapper, CallPrepayRule> implements CallPrepayRuleService {

    @Autowired
    private CallGeoCircleFenceMongoRepository callPrepayRuleMongoRepository;

    @Override
    public RestResult list(Integer current, Integer size, String customerRegionName) {
        Page<CallPrepayRulePresenter> page = new Page<>(current, size);
        IPage<CallPrepayRulePresenter> pages = baseMapper.getListPage(page, customerRegionName);
        for (CallPrepayRulePresenter presenter : pages.getRecords()) {
            if (presenter.getSpecifics().contains("geoFenceJudger")) {
                List<CallGeoCircleFenceMongo> fences = callPrepayRuleMongoRepository.getByRuleId(presenter.getId());
                List<CallPrepayRulePresenter.Fence> fenceVOs = new ArrayList<>();
                for (CallGeoCircleFenceMongo fence : fences) {
                    CallPrepayRulePresenter.Fence fenceVO = new CallPrepayRulePresenter.Fence();
                    fenceVO.setName(fence.getLocationName());
                    fenceVO.setLocation(fence.getLocation().toString());
                    fenceVO.setRadius(Convert.toInt(NumberUtil.mul(fence.getDistance(), Convert.toDouble(1000))));
                    fenceVOs.add(fenceVO);
                }
                presenter.setFence(fenceVOs);
            }
        }
        return RestResult.success(pages);
    }

    @Override
    public RestResult updateActive(CallPrepayRule callPrepayRule) {
        baseMapper.updateById(callPrepayRule);
        return RestResult.success();
    }

    @Override
    public RestResult deleteById(Long id) {
        baseMapper.deleteById(id);
        //删除mongo绑定的数据
        callPrepayRuleMongoRepository.deleteByRuleId(id);
        return RestResult.success();
    }

    @Override
    public RestResult getInfoById(Long id) {
        CallPrepayRule rule = baseMapper.selectById(id);
        CallPrepayRulePresenter presenter = BeanUtil.copyProperties(rule, CallPrepayRulePresenter.class);
        List<CallGeoCircleFenceMongo> fences = callPrepayRuleMongoRepository.getByRuleId(id);
        List<CallPrepayRulePresenter.Fence> fenceVOs = new ArrayList<>();
        for (CallGeoCircleFenceMongo fence : fences) {
            CallPrepayRulePresenter.Fence fenceVO = new CallPrepayRulePresenter.Fence();
            fenceVO.setMongoId(fence.getId().toString());
            fenceVO.setName(fence.getLocationName());
            fenceVO.setLocation(fence.getLocation().getX() + "," + fence.getLocation().getY());
            fenceVO.setRadius(Convert.toInt(NumberUtil.mul(fence.getDistance(), Convert.toDouble(1000))));
            fenceVOs.add(fenceVO);
        }
        presenter.setFence(fenceVOs);
        return RestResult.success(presenter);
    }

    @Override
    public RestResult updateById(CallPrepayRuleAddUpdateWrapper wrapper) {
        CallPrepayRule callPrepayRule = new CallPrepayRule();
        callPrepayRule.setId(wrapper.getId());
        callPrepayRule.setTitle(wrapper.getTitle());
        callPrepayRule.setRatio(wrapper.getRatio());
        callPrepayRule.setCustomerRegionId(wrapper.getCustomerRegionId());
        String ruleSelect = JSON.toJSONString(wrapper.getRuleSelect());
        if (ruleSelect.contains("customerJudger")) {
            callPrepayRule.setCompleteOrderNumber(wrapper.getCompleteOrderNumber());
        }
        if (ruleSelect.contains("rideAmountJudger")) {
            callPrepayRule.setCallEstimateAmount(wrapper.getCallEstimateAmount());
        }
        Dict ruleDict = Dict.create()
                .set("condition", wrapper.getRuleSelect())
                .set("expression", StrUtil.join("||", wrapper.getRuleSelect()));
        callPrepayRule.setSpecifics(JSON.toJSONString(ruleDict));
        baseMapper.updateById(callPrepayRule);
        if (ruleSelect.contains("geoFenceJudger")) {
            callPrepayRuleMongoRepository.deleteByRuleId(wrapper.getId());
            for (CallPrepayRuleAddUpdateWrapper.Fence fence : wrapper.getFence()) {
                String[] point = StrUtil.split(fence.getLocation(), ",");
                CallGeoCircleFenceMongo callPrepayRuleMongo = new CallGeoCircleFenceMongo()
                        .setRuleId(callPrepayRule.getId())
                        .setDistance(NumberUtil.div(Convert.toDouble(fence.getRadius()), Convert.toDouble(1000), 1))
                        .setLocation(new GeoJsonPoint(new Point(Convert.toDouble(point[0]), Convert.toDouble(point[1]))))
                        .setLocationName(fence.getName())
                        .setCustomerRegionId(wrapper.getCustomerRegionId())
                        .setCreatedAt(new Date());

                callPrepayRuleMongoRepository.save(callPrepayRuleMongo);
            }

        }
        return RestResult.success();
    }

    @Override
    public RestResult addFence(CallPrepayFenceWrapper callPrepayRule) {
        String[] point = StrUtil.split(callPrepayRule.getLocation(), ",");
        CallGeoCircleFenceMongo callPrepayRuleMongo = new CallGeoCircleFenceMongo()
                .setRuleId(callPrepayRule.getRuleId())
                .setDistance(NumberUtil.div(Convert.toDouble(callPrepayRule.getRadius()), Convert.toDouble(1000), 1))
                .setLocation(new GeoJsonPoint(new Point(Convert.toDouble(point[0]), Convert.toDouble(point[1]))))
                .setLocationName(callPrepayRule.getName())
                .setCustomerRegionId(callPrepayRule.getCustomerRegionId())
                .setCreatedAt(new Date());
        callPrepayRuleMongoRepository.save(callPrepayRuleMongo);
        return null;
    }

    @Override
    public RestResult add(CallPrepayRuleAddUpdateWrapper addWrapper) {
        CallPrepayRule callPrepayRule = new CallPrepayRule();
        callPrepayRule.setTitle(addWrapper.getTitle());
        callPrepayRule.setCustomerRegionId(addWrapper.getCustomerRegionId());
        callPrepayRule.setRatio(addWrapper.getRatio());
        String ruleSelect = JSON.toJSONString(addWrapper.getRuleSelect());
        if (ruleSelect.contains("customerJudger")) {
            callPrepayRule.setCompleteOrderNumber(addWrapper.getCompleteOrderNumber());
        }
        if (ruleSelect.contains("rideAmountJudger")) {
            callPrepayRule.setCallEstimateAmount(addWrapper.getCallEstimateAmount());
        }
        Dict ruleDict = Dict.create()
                .set("condition", addWrapper.getRuleSelect())
                .set("expression", StrUtil.join("||", addWrapper.getRuleSelect()));
        callPrepayRule.setSpecifics(JSON.toJSONString(ruleDict));
        baseMapper.insert(callPrepayRule);
        if (ruleSelect.contains("geoFenceJudger")) {
            callPrepayRuleMongoRepository.deleteByRuleId(addWrapper.getId());
            for (CallPrepayRuleAddUpdateWrapper.Fence fence : addWrapper.getFence()) {
                String[] point = StrUtil.split(fence.getLocation(), ",");
                CallGeoCircleFenceMongo callPrepayRuleMongo = new CallGeoCircleFenceMongo()
                        .setRuleId(callPrepayRule.getId())
                        .setDistance(NumberUtil.div(Convert.toDouble(fence.getRadius()), Convert.toDouble(1000), 1))
                        .setLocation(new GeoJsonPoint(new Point(Convert.toDouble(point[0]), Convert.toDouble(point[1]))))
                        .setLocationName(fence.getName())
                        .setCustomerRegionId(addWrapper.getCustomerRegionId())
                        .setCreatedAt(new Date());

                callPrepayRuleMongoRepository.save(callPrepayRuleMongo);
            }
        }
        return RestResult.success();
    }

//    @Override
//    public RestResult deleteMongoById(String mongoId) {
//        Optional<CallGeoCircleFenceMongo> callGeoCircleFence = callPrepayRuleMongoRepository.findById(new ObjectId(mongoId));
//        if (callGeoCircleFence.isPresent()) {
//            CallGeoCircleFenceMongo callGeoCircleFenceMongo = callGeoCircleFence.get();
//            Double distance = callGeoCircleFenceMongo.getDistance() * 1000;
//
//            callPrepayRuleMongoRepository.deleteByRuleId(callGeoCircleFenceMongo.getRuleId());
//        }
//
//
//        callPrepayRuleMongoRepository.deleteById(new ObjectId(mongoId));
//        return null;
//    }
}
